﻿package mortal.game.scene3D.ai
{
    import Message.Public.*;
    import __AS3__.vec.*;
    import com.gengine.core.frame.*;
    import com.gengine.debug.*;
    import extend.language.*;
    import flash.geom.*;
    import flash.utils.*;
    import mortal.component.gconst.*;
    import mortal.game.*;
    import mortal.game.cache.*;
    import mortal.game.events.*;
    import mortal.game.manager.*;
    import mortal.game.model.*;
    import mortal.game.mvc.*;
    import mortal.game.resource.*;
    import mortal.game.scene3D.ai.ais.*;
    import mortal.game.scene3D.ai.base.*;
    import mortal.game.scene3D.ai.data.*;
    import mortal.game.scene3D.layer3D.utils.*;
    import mortal.game.scene3D.map3D.AstarAnyDirection.data.*;
    import mortal.game.scene3D.map3D.mapToMapPath.*;
    import mortal.game.scene3D.map3D.sceneInfo.*;
    import mortal.game.scene3D.map3D.util.*;
    import mortal.game.scene3D.player.entity.*;
    import mortal.game.scene3D.util.*;
    import mortal.game.view.copy.petBreak.*;
    import mortal.game.view.guide.*;
    import mortal.game.view.guide.guideUse.*;
    import mortal.mvc.core.*;

    public class AIManager extends Object
    {
        private static var _aiList:Array = [];
        private static var _curAI:IAICommand;
        private static var _isCancelAll:Boolean = false;
        private static var _isWorking:Boolean = false;
        private static var _singleClickNoStop:Boolean = false;
        public static var endTime:int = -1;
        public static var version:int = 0;
        public static var lastTimerId:int;
        private static var _setNotStopTime:int = -1;

        public function AIManager()
        {
            return;
        }// end function

        public static function onAIControl(param1:int, ... args) : Boolean
        {
            args = null;
            var _loc_4:FollowFightAIData = null;
            var _loc_5:IEntity = null;
            var _loc_6:Boolean = false;
            var _loc_7:SPassTo = null;
            var _loc_8:SPassPoint = null;
            var _loc_9:MonsterPlayer = null;
            var _loc_10:int = 0;
            var _loc_11:int = 0;
            var _loc_12:Point = null;
            if (param1 != AIType.Follow_fight)
            {
                cancelAll();
            }
            switch(param1)
            {
                case AIType.Follow:
                {
                    addFollow(ThingUtil.selectEntity);
                    break;
                }
                case AIType.Follow_fight:
                {
                    _loc_4 = args[0] as FollowFightAIData;
                    _loc_5 = _loc_4.target as IEntity;
                    if (_loc_5 != null && GeomUtil.calcDistance(_loc_5.x2d, _loc_5.y2d, RolePlayer.instance.realX2d, RolePlayer.instance.y2d) > _loc_4.range)
                    {
                        cancelAll(false);
                    }
                    else
                    {
                        cancelAll(true);
                    }
                    addFollowFight(_loc_4);
                    break;
                }
                case AIType.ClickNpc:
                {
                    args = new Point(ThingUtil.selectEntity.x2d, ThingUtil.selectEntity.y2d);
                    addMoveTo(args, GameConst.NpcInDistance);
                    _loc_6 = false;
                    if (args[1] != null && args[1] == true)
                    {
                        _loc_6 = true;
                    }
                    addClickNpcAI(args[0], _loc_6);
                    break;
                }
                case AIType.FlyBoot:
                {
                    _loc_7 = args[0] as SPassTo;
                    if (_loc_7 != null && GameMapUtil.shouldUseAutoPathReplaceFlyBoot(_loc_7.mapId, _loc_7.toPoint.x, _loc_7.toPoint.y))
                    {
                        if (addMoveToOtherMap(Game.mapInfo.mapId, _loc_7.mapId, new Point(_loc_7.toPoint.x, _loc_7.toPoint.y)))
                        {
                            MsgManager.showRollTipsMsg(Language.getString(20609));
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else if (!addFlyBoot(_loc_7))
                    {
                        return false;
                    }
                    break;
                }
                case AIType.GoToAndPass:
                {
                    _loc_8 = args[0] as SPassPoint;
                    if (_loc_8 != null)
                    {
                        args = new Point();
                        args.x = _loc_8.point.x;
                        args.y = _loc_8.point.y;
                        addMoveTo(args, 0);
                        addPassToMap(_loc_8);
                    }
                    break;
                }
                case AIType.GoToAndJump:
                {
                    args = args[0] as Point;
                    if (args != null)
                    {
                        _loc_10 = Game.mapInfo.pieceWidth;
                        _loc_11 = Game.mapInfo.pieceHeight;
                        args.x = (int(args.x / _loc_10) + 0.5) * _loc_10;
                        args.y = (int(args.y / _loc_11) + 0.5) * _loc_11;
                        addMoveTo(args, 0);
                        _loc_12 = new Point(int(args.x / _loc_10) + 0.5, int(args.y / _loc_11) + 0.5);
                        addJump(_loc_12);
                    }
                    break;
                }
                case AIType.GoToOtherMap:
                {
                    if (!addMoveToOtherMap(args[0], args[1], args[2]))
                    {
                        return false;
                    }
                    break;
                }
                case AIType.AutoFight:
                {
                    addAutoFight(args[0]);
                    break;
                }
                case AIType.Collect:
                {
                    _loc_9 = args[0] as MonsterPlayer;
                    addMoveTo(new Point(_loc_9.x2d, _loc_9.y2d), _loc_9.entityInfo.bodySize + RolePlayer.instance.entityInfo.bodySize);
                    addCollectAI(_loc_9);
                    break;
                }
                case AIType.PetAutoFight:
                {
                    addPetAutoFight(args[0]);
                    break;
                }
                case AIType.FightBossToDead:
                {
                    addFightBossToDeadAI();
                    break;
                }
                default:
                {
                    break;
                }
            }
            if (_curAI != null && !_curAI.stopable)
            {
                return true;
            }
            start();
            return true;
        }// end function

        public static function CancelAllTeamporary() : void
        {
            if (_curAI == null)
            {
                return;
            }
            if (_curAI is AutoFightAI)
            {
                (_curAI as AutoFightAI).cancelAll();
                return;
            }
            cancelAll();
            return;
        }// end function

        public static function get curAI() : IAICommand
        {
            return _curAI;
        }// end function

        public static function set curAI(param1:IAICommand) : void
        {
            _curAI = param1;
            return;
        }// end function

        public static function get isWorking() : Boolean
        {
            return _isWorking;
        }// end function

        public static function get curStopabele() : Boolean
        {
            if (_curAI != null && !_curAI.stopable)
            {
                return false;
            }
            return true;
        }// end function

        public static function cancelAll(param1:Boolean = true) : Boolean
        {
            _isWorking = false;
            if (_curAI != null)
            {
                if (!_curAI.stopable)
                {
                    inPoolAllTobeStartAi();
                    return false;
                }
                _isCancelAll = true;
                AIFactory.instance.inAIData(_curAI.data);
                _curAI.stop(param1);
                _curAI = null;
                _isCancelAll = false;
            }
            inPoolAllTobeStartAi();
            endTime = FrameManager.flashFrame.getTime();
            singleClickNoStop = false;
            Dispatcher.dispatchEvent(new DataEvent(EventName.AI_Canceled));
            if (AutoFightAI.isWorking)
            {
                AutoFightAI.instance.stop(param1);
            }
            return true;
        }// end function

        public static function startByCheckIsRuning() : void
        {
            if (isWorking)
            {
                return;
            }
            start();
            return;
        }// end function

        public static function start() : void
        {
            var _loc_2:* = version + 1;
            version = _loc_2;
            SceenOperation.interruptToAI(startImpl, cancelAll);
            return;
        }// end function

        public static function startImpl() : void
        {
            if (_isCancelAll)
            {
                return;
            }
            if (_curAI != null)
            {
                AIFactory.instance.inAIData(_curAI.data);
                _curAI = null;
            }
            if (_aiList == null || _aiList.length == 0)
            {
                _isWorking = false;
                singleClickNoStop = false;
                Dispatcher.dispatchEvent(new DataEvent(EventName.AI_AllFinished));
                endTime = FrameManager.flashFrame.getTime();
                return;
            }
            _isWorking = true;
            _curAI = _aiList.shift();
            _curAI.start(start);
            return;
        }// end function

        private static function inPoolAllTobeStartAi() : void
        {
            var _loc_2:IAICommand = null;
            if (_aiList == null || _aiList.length == 0)
            {
                return;
            }
            var _loc_1:int = 0;
            while (_loc_1 < _aiList.length)
            {
                
                _loc_2 = _aiList[_loc_1];
                AIFactory.instance.inAIData(_loc_2.data);
                _loc_1++;
            }
            _aiList = [];
            return;
        }// end function

        public static function addAI(param1:IAICommand) : void
        {
            _aiList.push(param1);
            return;
        }// end function

        public static function addAIs(param1:Array) : void
        {
            _aiList = _aiList.concat(param1);
            return;
        }// end function

        public static function addAutoFight(param1:int = -1, param2:Dictionary = null, param3:int = -1) : void
        {
            var _loc_4:* = AutoFightAI.instance;
            var _loc_5:* = AIFactory.instance.outAIData();
            _loc_4.data = _loc_5;
            _loc_5.range = param1;
            _loc_5.params = param2;
            _loc_5.times = param3;
            _aiList.push(_loc_4);
            return;
        }// end function

        public static function addFightBossToDeadAI() : void
        {
            var _loc_1:* = new FollowFightBossToDeadAI();
            _loc_1.data = AIFactory.instance.outAIData();
            _aiList.push(_loc_1);
            return;
        }// end function

        public static function addPetAutoFight(param1:int = -1, param2:Dictionary = null, param3:int = -1) : void
        {
            var _loc_4:* = new PetAutoFightAI();
            var _loc_5:* = AIFactory.instance.outAIData();
            _loc_4.data = _loc_5;
            _loc_5.range = param1;
            _loc_5.params = param2;
            _loc_5.times = param3;
            _aiList.push(_loc_4);
            return;
        }// end function

        public static function addMoveTo(param1:Point, param2:int = -1, param3:Boolean = false) : void
        {
            var _loc_4:* = new MoveAI();
            var _loc_5:* = AIFactory.instance.outAIData();
            _loc_4.data = _loc_5;
            _loc_5.target = param1;
            MoveAI(_loc_4).range = param2;
            if (param3)
            {
                _aiList.unshift(_loc_4);
            }
            else
            {
                _aiList.push(_loc_4);
            }
            return;
        }// end function

        public static function addMoveByPath(param1:Array, param2:int = -1, param3:Boolean = false) : void
        {
            var _loc_4:* = new MoveByPathAI();
            var _loc_5:* = AIFactory.instance.outAIData();
            _loc_4.data = _loc_5;
            _loc_5.params = param1;
            MoveByPathAI(_loc_4).range = param2;
            if (param3)
            {
                _aiList.unshift(_loc_4);
            }
            else
            {
                _aiList.push(_loc_4);
            }
            return;
        }// end function

        public static function addJump(param1:Point, param2:Boolean = false) : void
        {
            var _loc_3:* = new JumpAI();
            var _loc_4:* = AIFactory.instance.outAIData();
            _loc_3.data = _loc_4;
            _loc_4.target = param1;
            if (param2)
            {
                _aiList.unshift(_loc_3);
            }
            else
            {
                _aiList.push(_loc_3);
            }
            return;
        }// end function

        public static function addFlyBoot(param1:SPassTo) : Boolean
        {
            if (!FlyBootAI.checkCanFly(param1.mapId))
            {
                return false;
            }
            var _loc_2:* = new FlyBootAI();
            var _loc_3:* = new AIData();
            _loc_3.meRole = RolePlayer.instance;
            _loc_3.scene = Game.scene;
            _loc_3.params = param1;
            _loc_2.data = _loc_3;
            _aiList.push(_loc_2);
            return true;
        }// end function

        public static function addFollow(param1:IEntity, param2:Boolean = false) : void
        {
            var _loc_3:IAICommand = null;
            var _loc_4:AIData = null;
            _loc_3 = new FollowAI();
            _loc_4 = AIFactory.instance.outAIData();
            _loc_3.data = _loc_4;
            _loc_4.target = ThingUtil.selectEntity;
            if (param2)
            {
                _aiList.unshift(_loc_3);
            }
            else
            {
                _aiList.push(_loc_3);
            }
            return;
        }// end function

        public static function addPassToMap(param1:SPassPoint) : void
        {
            var _loc_2:IAICommand = null;
            var _loc_3:AIData = null;
            _loc_2 = new PassAI();
            _loc_3 = AIFactory.instance.outAIData();
            _loc_2.data = _loc_3;
            _loc_3.params = param1;
            _aiList.push(_loc_2);
            return;
        }// end function

        public static function addFlyBootToCopy(param1:int, param2:int, param3:Point, param4:int = 0, param5:Function = null, param6:Array = null) : Boolean
        {
            var p:Point;
            var delayBootFlyToCopy:Function;
            var info:SceneInfo;
            var passPoint:SPassPoint;
            var passTo:SPassTo;
            var ppp:Point;
            var fromMapId:* = param1;
            var toMapId:* = param2;
            var targetPoint:* = param3;
            var moveRange:* = param4;
            var callback:* = param5;
            var params:* = param6;
            delayBootFlyToCopy = function () : void
            {
                addFlyBootToCopy(MapFileUtil.mapID, toMapId, targetPoint, moveRange, callback, params);
                return;
            }// end function
            ;
            if (fromMapId == toMapId)
            {
                addMoveTo(targetPoint, moveRange);
                if (callback != null)
                {
                    callback.apply(null, params);
                }
                return true;
            }
            var path:* = MapPathSearcher.findMapPath(fromMapId, toMapId);
            if (path == null || path.length == 0)
            {
                info = SceneConfig.instance.getSceneInfo(fromMapId);
                if (info.passInfos.length == 1)
                {
                    passPoint = info.passInfos[0] as SPassPoint;
                    passTo = passPoint.passTo[0] as SPassTo;
                    if (passTo == null || passTo.toPoint == null)
                    {
                        ppp = new Point();
                        ppp.x = passPoint.point.x;
                        ppp.y = passPoint.point.y;
                        addMoveTo(ppp, 0);
                        Log.error("意外找出口：1");
                        addPassToMap(passPoint);
                        addDelayAI(200);
                        addCallback(delayBootFlyToCopy);
                        return true;
                    }
                }
                info = SceneConfig.instance.getSceneInfo(toMapId);
                MsgManager.showRollTipsMsg(Language.getString(20610));
                return false;
            }
            passPoint = path[(path.length - 1)];
            passTo = new SPassTo();
            passTo.mapId = passPoint.mapId;
            passTo.toPoint = new SPoint();
            passTo.toPoint.x = passPoint.point.x;
            passTo.toPoint.y = passPoint.point.y;
            addFlyBoot(passTo);
            Log.error("意外找出口：2");
            addPassToMap(passPoint);
            addDelayAI(200);
            addMoveTo(targetPoint, moveRange);
            if (callback != null)
            {
                callback.apply(null, params);
            }
            return true;
        }// end function

        public static function addMoveToOtherMap(param1:int, param2:int, param3:Point, param4:int = 0, param5:Function = null, param6:Array = null) : Boolean
        {
            var toOtherMapAfterPassAI:Function;
            var info:SceneInfo;
            var passPoint:SPassPoint;
            var passTo:SPassTo;
            var ppp:Point;
            var tp:Point;
            var fromMapId:* = param1;
            var toMapId:* = param2;
            var targetPoint:* = param3;
            var moveRange:* = param4;
            var callback:* = param5;
            var params:* = param6;
            toOtherMapAfterPassAI = function () : void
            {
                addMoveToOtherMap(MapFileUtil.mapID, toMapId, targetPoint, moveRange, callback, params);
                return;
            }// end function
            ;
            if (fromMapId == toMapId)
            {
                if (targetPoint != null)
                {
                    addMoveTo(targetPoint, moveRange);
                }
                if (callback != null)
                {
                    callback.apply(null, params);
                }
                return true;
            }
            var path:* = MapPathSearcher.findMapPath(fromMapId, toMapId);
            if (path == null || path.length == 0)
            {
                info = SceneConfig.instance.getSceneInfo(fromMapId);
                if (info.passInfos.length >= 1)
                {
                    passPoint = info.passInfos[0] as SPassPoint;
                    passTo = passPoint.passTo[0] as SPassTo;
                    if (passTo == null || passTo.toPoint == null)
                    {
                        ppp = new Point();
                        ppp.x = passPoint.point.x;
                        ppp.y = passPoint.point.y;
                        addMoveTo(ppp, 0);
                        addPassToMap(passPoint);
                        addDelayAI(200);
                        addCallback(toOtherMapAfterPassAI);
                        Log.error("意外找出口：fromMapId=" + fromMapId + ", toMapId=" + toMapId);
                        return true;
                    }
                }
                info = SceneConfig.instance.getSceneInfo(toMapId);
                if (!GuideController.isLinkByAutoTask)
                {
                    MsgManager.showRollTipsMsg(Language.getString(20611));
                }
                return false;
            }
            var i:int;
            while (i < path.length)
            {
                
                passPoint = path[i];
                passTo = passPoint.passTo[0] as SPassTo;
                tp = new Point(passPoint.point.x, passPoint.point.y);
                tp.x = (int(tp.x / Game.mapInfo.pieceWidth) + 0.5) * Game.mapInfo.pieceWidth;
                tp.y = (int(tp.y / Game.mapInfo.pieceHeight) + 0.5) * Game.mapInfo.pieceHeight;
                addMoveTo(tp, 0);
                Log.error("意外找出口：33333333,,,,,fromMapId=" + fromMapId + ", toMapId=" + toMapId);
                addPassToMap(passPoint);
                if (PassUtil.isPassToCopyType(passTo))
                {
                    addCallback(toOtherMapAfterPassAI);
                    return true;
                }
                i = (i + 1);
            }
            if (targetPoint != null)
            {
                addMoveTo(targetPoint, moveRange);
            }
            if (callback != null)
            {
                callback.apply(null, params);
            }
            return true;
        }// end function

        public static function addDelayAI(param1:int) : void
        {
            var _loc_2:IAICommand = null;
            var _loc_3:AIData = null;
            _loc_2 = new DelayAI();
            _loc_3 = AIFactory.instance.outAIData();
            _loc_2.data = _loc_3;
            _loc_3.params = param1;
            _aiList.push(_loc_2);
            return;
        }// end function

        public static function addFollowFight(param1:FollowFightAIData, param2:Boolean = false) : void
        {
            var _loc_3:IAICommand = null;
            if (param1.skillInfo == null)
            {
                param1.skillInfo = PetBreakCopyUtil.firstSkill;
                if (param1.skillInfo == null)
                {
                    return;
                }
            }
            _loc_3 = new FollowFightAI();
            _loc_3.data = param1;
            if (param2)
            {
                _aiList.unshift(_loc_3);
            }
            else
            {
                _aiList.push(_loc_3);
            }
            return;
        }// end function

        public static function addFightOnce(param1:FollowFightAIData) : void
        {
            var _loc_2:* = new FightOnceAI();
            _loc_2.data = param1;
            _aiList.push(_loc_2);
            return;
        }// end function

        public static function addClickNpcAI(param1:int, param2:Boolean = false) : void
        {
            var _loc_3:* = new ClickNpcAI();
            var _loc_4:* = AIFactory.instance.outAIData();
            _loc_4.params = param1;
            _loc_4.target = param2;
            _loc_3.data = _loc_4;
            _aiList.push(_loc_3);
            return;
        }// end function

        public static function addCallback(param1:Function, param2:Object = null) : void
        {
            var _loc_3:* = new CallBackData();
            _loc_3.meRole = RolePlayer.instance;
            _loc_3.scene = Game.scene;
            var _loc_4:* = new CallBackAI();
            _loc_4.data = _loc_3;
            _loc_3.callback = param1;
            _loc_3.params = param2;
            _aiList.push(_loc_4);
            return;
        }// end function

        public static function addCollectAI(param1:MonsterPlayer) : void
        {
            var _loc_2:* = new CollectAI();
            var _loc_3:* = AIFactory.instance.outAIData();
            _loc_3.target = param1;
            _loc_2.data = _loc_3;
            _aiList.push(_loc_2);
            return;
        }// end function

        public static function gotoOrSendtoNpc(param1:int, param2:Boolean = false) : void
        {
            var preShowNpc:Function;
            var sPassTo:SPassTo;
            var npcId:* = param1;
            var isSend:* = param2;
            preShowNpc = function (param1:Array) : void
            {
                if (lastTimerId > 0)
                {
                    clearTimeout(lastTimerId);
                    lastTimerId = -1;
                }
                var _loc_2:* = ThingUtil.npcUtil.getNpc(npcId);
                if (_loc_2 == null)
                {
                    lastTimerId = setTimeout(preShowNpc, 50, param1);
                    return;
                }
                AIManager.addClickNpcAI(npcId);
                if (!AIManager.isWorking)
                {
                    AIManager.start();
                }
                return;
            }// end function
            ;
            var sceneInfo:* = SceneConfig.instance.getSceneInfoByNpcId(npcId);
            if (sceneInfo == null)
            {
                return;
            }
            var npcInfo:* = sceneInfo.getNpcInfo(npcId);
            if (npcInfo == null)
            {
                return;
            }
            AIManager.cancelAll();
            if (isSend)
            {
                sPassTo = new SPassTo();
                sPassTo.mapId = npcInfo.snpc.mapId;
                sPassTo.toPoint = npcInfo.snpc.point;
                AIManager.onAIControl(AIType.FlyBoot, sPassTo);
                AIManager.addCallback(preShowNpc, [null, 50]);
            }
            else
            {
                AIManager.onAIControl(AIType.GoToOtherMap, MapFileUtil.mapID, npcInfo.snpc.mapId, new Point(npcInfo.snpc.point.x, npcInfo.snpc.point.y));
                addClickNpcAI(npcId);
            }
            return;
        }// end function

        public static function get singleClickNoStop() : Boolean
        {
            if (Cache.instance.role.roleInfo.level >= GameConst.SingleClickNoStopLv)
            {
                return false;
            }
            if (_curAI == null || !_singleClickNoStop)
            {
                return false;
            }
            if (_curAI is MoveAI || _curAI is MoveByPathAI || _curAI is FollowAI || _curAI is FollowFightAI || _curAI is AutoFightAI)
            {
                return true;
            }
            if (GuideUseWinBase.isShowing)
            {
                return true;
            }
            return false;
        }// end function

        public static function set singleClickNoStop(param1:Boolean) : void
        {
            _singleClickNoStop = param1;
            if (param1)
            {
                _setNotStopTime = FrameManager.flashFrame.getTime();
            }
            return;
        }// end function

    }
}
